#ifndef TIMER_TIMERMANAGER_H
#define TIMER_TIMERMANAGER_H

#include "Timer.h"
#include "utility/Noncopyable.h"
#include "utility/chrono.h"
#include "utility/func.h"

#include <map>
#include <memory>
#include <set>

class Eventloop;
class IOchannel;

class TimerManager final {
public:
    explicit TimerManager(Eventloop &loop);
    ~TimerManager();

    TimerID add(const TrivialFunc &callback, Utility::duration delay, bool isOneShot);
    void cancel(TimerID id);

private:
    NONCOPYABLE(TimerManager);

    bool _insert(Timer &&timer);
    void _read_callback();
    void _run_expired_funcs(
        std::vector<Timer> &&expiredTimers, Utility::timepoint now);
    std::vector<Timer> _take_expired_timers(Utility::timepoint now);

    std::map<std::pair<Utility::timepoint, TimerID>, Timer> _timers;
    std::map<TimerID, Utility::timepoint> _activeTimerIDMap;
    std::set<TimerID> _cancelingTimerIDs;
    Eventloop &_loop;
    const std::unique_ptr<IOchannel> _channel;
    bool _callingExpiredTimers;
};


#endif